package praktikumid.w10.p2;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * Concrete shape - CloseShape. A closed shape is
 * a polygon. It has points, every point is connected
 * to the next point. The last one is connected
 * to the first one. 
 * <p>
 * During the drawing, the first and the last point
 * are not connected. They are connected after the shape
 * is finished, which takes place after double click.
 * @author Ago
 *
 */
public class ClosedShape extends Shape {

	/**
	 * A list of points, which will be connected
	 * by lines.
	 */
	private List<Point> points = new ArrayList<Point>();
	
	/**
	 * To show the line while dragging the mouse,
	 * we need a separate boolean value which
	 * states that the last point in the points list
	 * is not fixed, but can (and will) be moved.
	 */
	private boolean lastPointDragging = false;
	
	@Override
	public void paintComponent(Graphics g) {
		// let's call parent paintComponent
		// which deals with colors
		super.paintComponent(g);
		// let's connect every point with the last point
		// starting from the second (we cannot
		// start from the first (index 0) point, 
		// as it does not have the previous point).
		for (int i = 1; i < points.size(); i++) {
			g.drawLine(points.get(i).x, points.get(i).y,
					points.get(i - 1).x,
					points.get(i - 1).y);
		}
		
		if (isFinished) {
			// after we have finished, let's connect
			// the first and the last points
			if (points.size() > 0) {
				g.drawLine(points.get(0).x, points.get(0).y,
						getLastPoint().x,
						getLastPoint().y);
				
			}
		}
		
	}

	@Override
	public void drag(MouseEvent e) {
		if (!lastPointDragging) {
			// if the last point is not meant for dragging,
			// we need to add a point here
			
			// if we don't have any points at all
			// we need to have the start point
			// from which we are dragging a new added point.
			// Otherwise it happens that we would
			// drag the first (and the only) point.
			if (points.size() == 0) points.add(e.getPoint());
			
			// let's add a new point which we will be dragging.
			points.add(e.getPoint());
			// and let's change the value for lastPointDragging
			lastPointDragging = true;
		}
		// if lastPointDragging is true,
		// we can move the last point.
		// Here this could also be done in "else"
		// block
		getLastPoint().setLocation(e.getPoint());
	}

	@Override
	public void click(MouseEvent e) {
		// if we click, we add a new point
		points.add(e.getPoint());
		if (e.getClickCount() > 1) {
			// double click (more than 1 click)
			// we finish the shape
			isFinished = true;
		}
	}

	@Override
	public void release(MouseEvent e) {
		// if we release, we just state
		// that the last point is not for dragging anymore.
		// It may happen, that this value is false
		// anyway, but it doesn't too much harm
		// to just set it false without checking.
		lastPointDragging = false;
	}
	
	/**
	 * Returns the last Point of the shape.
	 * @return Last point
	 */
	public Point getLastPoint() {
		// if there are no points, returns null
		if (points.size() == 0) return null;
		return points.get(points.size() - 1);
	}

	@Override
	public int getDistance(Point p) {
		// we find the distance of p
		// from every point in the shape
		// and return the smallest distance.
		int minDistance = Integer.MAX_VALUE;
		for (Point p2 : points) {
			int d = (int) p.distance(p2);
			if (d < minDistance) {
				minDistance = d;
			}
		}
		return minDistance;
	}
	@Override
	public void move(int dx, int dy) {
		// when moving the shape,
		// we need to move all the points
		for (Point p : points) {
			p.x = p.x + dx;
			p.y = p.y + dy;
		}
		
	}

}
